#ifndef _WT_WORKER_H
#define _WT_WORKER_H

typedef struct WtThreadStorageT
{
  int contextId;
} WtThreadStorage;

typedef struct WtPointerObjRegistryT
{
  /* Map of string IDs to objects */
  Tcl_HashTable idMap;
} WtPointerObjRegistry;

typedef struct WtServerT
{
  int isPersistent;
  int recycle;
  server_rec *apServer;
  Tcl_Interp *interp;
  Tcl_Obj *inheritedSettings;
  Tcl_Obj *interpCreateScript;
  TcL_Obj *interpDestroyScript;
  Tcl_Obj *includeStartScript;
  Tcl_Obj *includeEndScript;
  Tcl_Obj *includeNamespace;
  int addHeaderTrailer;
  Tcl_Obj *includeHeader;
  Tcl_Obj *includeTrailer;
  Tcl_Obj *scriptStartString;
  Tcl_Obj *scriptEndString;
  int evalText;
  Tcl_Obj *scriptStack;
  Tcl_Obj *errorHandler;
} WtServer;

typedef struct WtRequest
{
  request_rec *apReq;
  ApacheRequest *apWeb;
  ApacheCookieJar *apCookies;
  int envInitialized;
  Tcl_Obj *serverVars;
  Tcl_Obj *headers;
  int inputInitialized;
  Tcl_Obj *queryParams;
  Tcl_Obj *postParams;
  Tcl_Obj *params;
  Tcl_Obj *cookies;
  Tcl_Obj *uploads;
  Tcl_Obj *uploadHandler;
  Tcl_Obj *uploadHandlerData;
  Tcl_Obj *startScript;
  Tcl_Obj *endScript;
} WtRequest;

typedef struct WtResponseT
{
  Tcl_Channel chan;
  Tcl_Obj *cookies;
  Tcl_Obj *headers;
  Tcl_Obj *successHeaders;
  int headersSent;
  int status;
} WtResponse;

typedef struct WtWebContextT
{
  WtServer server;
  WtRequest request;
  WtResponse response;
} WtWebContext;

typedef struct WtContextT
{
  WtWebContext *active;
  WtWebContext persistent;
  WtPointerObjRegistry objRegistry;
  Tcl_Channel webChannel;
  Tcl_HashTable *optionKeys;
  Tcl_Obj *defaultSettings;
  int reuseInterp;
} WtContext;

module MODULE_VAR_EXPORT wtcl_module;
extern WtContext **WtContexts;
extern Tcl_ChannelType WtOutChanType;

WtThreadStorage *WtGetThreadStorage();
WtContext *WtGetContext();
int WtGetContextId();
void WtSetContextId(int);
WtContext *WtGetInterpContext(Tcl_Interp *);

int WtThreadsPerChild();
void WtInitServer(server_rec *s, pool *p);
void WtInitContext(WtContext *w, server_rec *s, pool *p, Tcl_Obj *serverConf);
void WtCreateInterp(WtContext *w, int isPersistent);
void WtEndServer(server_rec *s, pool *p);
void WtFreeContext(WtContext *w);
void WtInitRequest(WtContext *w);
void WtEndRequest(WtContext *w);
int WtProcessRequest(request_rec *r);
void WtRunPage(WtContext *w);
int WtHeadersSent(WtContext *w);
int WtSendHeaders(WtContext *w);
int WtCmdInitRequest(Tcl_Interp *interp);
int WtReadRequest(WtContext *w, int setError);
void WtLoadRequestCookies(WtContext *w);
void WtLoadRequestFiles(WtContext *w);
void WtInitResponse(WtContext *w);
void WtLoadResponseCookies(WtContext *w);
Tcl_Obj *WtGetServerConf(server_rec *s);
Tcl_Obj *WtGetRequestConf(request_rec *r);

#endif /* !_WT_WORKER_H */
